package com.moleq.device;

import jp.co.casio.caios.framework.device.DeviceCommon;
import jp.co.casio.caios.framework.device.SerialCom;

public abstract class BasePinPad implements IBaseDevice,ISignatureCapture {

	public static final int TRANSACTION_SUCCESSED = 100;
	public static final int TRANSACTION_FAILURE = 101;
	public static final int TRANSACTION_TIMEOUT = 102;
	
	public static final int PAYMENT_TIMEOUT = 99;
	public static final int PAYMENT_FAILED = 98;
	public static final int PAYMENT_SUCCEED= 96;
	
	public static final int DOSIGNATURE_TIMEOUT = 105;
	public static final int DOSIGNATURE_SUCCEED = 103;
	public static final int DOSIGNATURE_FAILED = 104;
	
	public static final int GETSIGNATURE_TIMEOUT = 108;
	public static final int GETSIGNATURE_FAILED = 107;
	public static final int GETSIGNATURE_SUCCEED = 106;

	public static final String RESULT_OK = "result.ok";
	public static final String RESULT_DECLINE = "result.decline";
	public static final String RESULT_ABORTED = "result.aborted";
	public static final String RESULT_TIMEOUT = "result.timeout";
	public static final String RESULT_DUPLICATE_TRANSACTION = "result.duplicate.transaction";
	public static final String RESULT_TERMINAL_ERROR = "result.terminal.error";
	public static final String RESULT_TRACK_INVALID = "result.track.invalid";
	public static final String RESULT_SWIPE_ERROR = "result.swipe.error";
	public static final String RESULT_COMM_ERROR = "result.comm.error";
	
	public static final int TIME_OUT = 89;
	

	// public String RefNum = "";

	// public boolean Upload = false;

	public PaxPinPadSetting mPinPadSetting;
	
	// com setting
	private int mPort;
	private int mBaudRate;
	private int mBitLen;
	private int mParityBit;
	private int mStopBit;

	private SerialCom mSerialCom;
	public IDeviceEvent mListener;
	private LocalDevice mDeviceState;
	protected boolean mIsConnected = false;
	protected boolean mIsEnable = false;
//	public String Amount;
	public boolean isSignatureCapture = false;
	public boolean isForce = false;
	public boolean isUploadSignatureCapture = false;
	public int invalidDupTransCount = 3;
	protected int currentDupTransCount = 0;
	protected OnSignatureListener mSignatureListener = null;
	
	// request
	protected MPaymentRequest mPaymentRequest = null;
	
	// response
	protected MPaymentResponse mPaymentResponse = null;
	
	
	public int SignStatusNum = -1;
	public double SignMinAmt = 0;
	
	public double PayAmt = 0;

//	public void  reset(){
//		isForce = false;
//		currentDupTransCount = 0;
//	}
	
	@Override
	public LocalDevice getState() {
		// TODO Auto-generated method stub
		return null;

	}

	@Override
	public void onDisconnect() {
		if (this.mDeviceState == LocalDevice.OPEN_STATE) {
			if (mSerialCom != null) {
				mSerialCom.disconnectCom();
				mSerialCom.close();
				mSerialCom = null;
				mIsConnected = false;
				mDeviceState = LocalDevice.CLOSE_STATE;
			}
		}

	}

	@Override
	public void onConnect() {
		if (mSerialCom == null) {
			mSerialCom = new SerialCom();
		}

		mIsConnected = false;

		boolean result = false;
		int response = 0;

		response = mSerialCom.open(mPort, DeviceCommon.DEVICE_MODE_COMMON, DeviceCommon.DEVICE_HOST_LOCALHOST);

		if (response != 0) {
			mDeviceState = LocalDevice.CLOSE_STATE;

			mListener.onErrorEvent("Faild to open Serial port.");
			return;
		}

		result = mSerialCom.connectCom(mBaudRate, mBitLen, mParityBit, mStopBit, SerialCom.SERIAL_FLOW_NON);

		if (result != true) {
			mDeviceState = LocalDevice.CLOSE_STATE;

			mListener.onErrorEvent("Faild to connect serial port.");
			return;
		}

		mSerialCom.setControl(SerialCom.SERIAL_IO_CTS);
		mSerialCom.setControl(SerialCom.SERIAL_IO_RTS);

		mIsConnected = true;
		mDeviceState = LocalDevice.OPEN_STATE;

	}

	@Override
	public void setCallbackEvent(IDeviceEvent impl) {
		mListener = impl;

	}

	@Override
	public void setComPort(int comPort) {
		// TODO Auto-generated method stub

	}

	@Override
	public void sendCmd(String strCommand) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onClearBuffer() {
		// TODO Auto-generated method stub

	}

	// @Override
	// public void ProcessTrans() {
	// // TODO Auto-generated method stub
	//
	// }

	public void setPinPadSetting(PaxPinPadSetting setting) {

		mPinPadSetting = setting;

		if (mPinPadSetting == null)
			return;

		// set port
		switch (setting.getPort()) {
		case 1:
			mPort = SerialCom.SERIAL_TYPE_COM1;
			break;
		case 2:
			mPort = SerialCom.SERIAL_TYPE_COM2;
			break;
		case 3:
			mPort = SerialCom.SERIAL_TYPE_COM3;
			break;
		case 4:
			mPort = SerialCom.SERIAL_TYPE_COM4;
			break;
		case 5:
			mPort = SerialCom.SERIAL_TYPE_COM5;
			break;

		}

		// set baud rate
		String baudrate = setting.getBaud();
		if (baudrate.equals("38400")) {
			mBaudRate = SerialCom.SERIAL_BOUDRATE_38400;
		} else if (baudrate.equals("19200")) {
			mBaudRate = SerialCom.SERIAL_BOUDRATE_19200;
		} else if (baudrate.equals("9600")) {
			mBaudRate = SerialCom.SERIAL_BOUDRATE_9600;
		} else if (baudrate.equals("4800")) {
			mBaudRate = SerialCom.SERIAL_BOUDRATE_4800;
		} else if (baudrate.equals("2400")) {
			mBaudRate = SerialCom.SERIAL_BOUDRATE_2400;
		} else if (baudrate.equals("1200")) {
			mBaudRate = SerialCom.SERIAL_BOUDRATE_1200;
		}

		// set bit len
		switch (setting.getDataBits()) {
		case 7:
			mBitLen = SerialCom.SERIAL_BITLEN_7;
			break;
		case 8:
			mBitLen = SerialCom.SERIAL_BITLEN_8;
			break;
		}

		// set parity
		String parity = setting.getParity();
		if (parity.equals("E")) {
			mParityBit = SerialCom.SERIAL_PARITY_EVEN;
		} else if (parity.equals("N")) {
			mParityBit = SerialCom.SERIAL_PARITY_NON;
		} else if (parity.equals("O")) {
			mParityBit = SerialCom.SERIAL_PARITY_ODD;
		}

		// set Stop Bit
		switch (setting.getStopBits()) {
		case 1:
			mStopBit = SerialCom.SERIAL_STOP_1;
			break;
		case 2:
			mStopBit = SerialCom.SERIAL_STOP_2;
			break;

		}

		String signatureFlag = setting.getIsSignatureCapture();
		isSignatureCapture = false;
		if (signatureFlag.equals("1")) {
			isSignatureCapture = true;
		}
	}

	@Override
	public boolean isConnected() {
		// TODO Auto-generated method stub
		return mIsConnected;
	}

	public boolean isEnable() {
		// TODO Auto-generated method stub
		return mIsEnable;
	}
	
	public void setUploadSignatureCapture(boolean enable){
		isUploadSignatureCapture = enable;
	}
	
	protected void sleep(int time) {
		try {
			Thread.sleep(time);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public abstract void initialize();

	public abstract void ProcessPayment();
	
	@Override
	public abstract void doSignature() ;

	@Override
	public abstract void getSignature();

	public void setOnSignatureListener(OnSignatureListener l) {
		this.mSignatureListener = l;

	}
	
	public void bindPaymentRequest(MPaymentRequest request) {
		mPaymentRequest = request;
		
	}
	
	public void bindPaymentResponse(MPaymentResponse response){	
		mPaymentResponse = response;
	}
	
	public void reset() {
		SignStatusNum = -1;
		SignMinAmt = 0;
		PayAmt = 0;
	}

	public interface OnSignatureListener {
		public void onDoSignature(int what, Object obj);
		
		public void onSignatureTimeOut();

		public void onGetSignature(int what, Object obj);
		
		public void onError(int what, Object obj);

	}

}
